/**
 *
 * @file output.c
 *
 * @brief This file contain all the printout fonctions
 *
 * $Id : $   
 * */

/*
 * This file is part of Tsar.
 *
 * Tsar is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Tsar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Tsar.  If not, see <http://www.gnu.org/licenses/>.
 */


/* I N C L U D E S    */
#include <utils.h>
#include <output.h>


/* -- G L O B A L  V A R I A B L E S (huh) -- */
FILE * ReportFile = NULL;
unsigned char VerbosityLevel = 0;
bool_t DebugEnabled = false;



/* Emergency case */
void die( char * str )
{
    perror( str );
    exit( EXIT_FAILURE );
}

void Perror( char * str )
{
    print_error( "[!] %s : %s\n", str, strerror( errno ) );
}

/* Log a simple error */
void print_error( char * fmt, ... )
{
    va_list ap;

    va_start( ap, fmt );
    /* Force printing, whatever verbosity level is defined */
    print_and_flush( stderr, fmt, ap );
    print_and_flush( ReportFile, fmt, ap );
    va_end( ap );
}

/* Exit but let us choose a formatted exit message */
void fatal( char * fmt, ... )
{
    va_list ap;

    va_start( ap, fmt );
    print_and_flush( stderr, fmt, ap );
    print_and_flush( ReportFile, fmt, ap );
    va_end( ap );
    exit( EXIT_FAILURE );
}

/* Print only if */
void debug( char *fmt, ...  )
{
    va_list ap;

    va_start( ap, fmt );
    if ( DebugEnabled )
    {
        print_and_flush( stderr, fmt, ap );
        print_and_flush( ReportFile, fmt, ap );
    }
    va_end( ap );
}

/* Our printf like function */
void print( int priority, char *fmt, ... )
{
    va_list ap;

    va_start( ap, fmt );
    /* Messages will be discarded if their priority is not in the allowed range */
    if ( priority <= VerbosityLevel )
    {
        /* if allowed the message is printed out on stdout */
        print_and_flush( stdout, fmt, ap );
        /* and in a logfile if anyone has been supplied */
        print_and_flush( ReportFile, fmt, ap );  
    }
    va_end( ap );
}

void init_output( opt_t * o )
{
    /* If a logfile has been specified */
    if ( o->outputFile != NULL )
    {
        /* Try to open it... Fopen is a success-or-die wrapper for fopen */
        ReportFile = Fopen( o->outputFile, "w+" );
    }
    /* Store verbosity level set by user and debug state (enabled/disabled) */
    VerbosityLevel = o->verbosityLevel;
    DebugEnabled   = o->debug; 
}

void print_and_flush( FILE * stream, const char * format, va_list ap )
{
    /* Catch NULL streams (eg. No output file supplied) */
    if ( stream == NULL )
        return;
    /* Print and flush on success */
    if ( ( vfprintf( stream, format, ap ) ) >= 0 ) 
    {
        /* Force flushing */
        fflush( stream );
    }
    else
    {
        /* No need to continue if we cannot even print anything out */
        die( "vfprintf" );  
    }
}

/* Shutdown output system */
void end_output( void )
{
    /* Close logfile if any */
    if ( ReportFile != NULL )
    {
        if ( ( fclose( ReportFile ) ) == EOF )
        {
            die( "fclose" );
        }
    }
}

